// @author U099151W Sun Chenchen
// all functions in this file  are implemented by the author unless specifically indicated
var Grid = function() {
    this.done = 0;
    this.indexer;
    this.timer = 0;
    this.semaphore = 0;
    this.refresh_timer = 0;
    this.end;
    var _buildingList = [];
    this.setNewBuilding = function(building_args) {
        _buildingList.push(building_args);
    };
    this.getBuildings = function() {
        return _buildingList;
    };
    this.getPortalByPosition = function(x, y) {
        for (var i=0; i<_buildingList.length; i++) {
            var building = _buildingList[i];
            for (var j=0; j<building.portals.length; j++) {
                if (building.portals[j].x === x || building.portals[j] === y) {
                    return building.obj;
                }
            }
        }
        return false;
    };
    this.getPortals = function() {

    };

    var _NPCs = {

    };
    this.getNPCs = function() {
        return _NPCs;
    };
    this.isEmpty = function() {
        for (var type in _NPCs) {
            if (_NPCs[type].length !== 0) {
                return false;
            }
        }
        for (var i=0; i<_buildingList.length; i++) {
            if(!_buildingList[i].obj.isEmpty()) {
                return false;
            }
        }
        return true;
    };

    var _type;
    this.getType = function() {
        return _type;
    };

    this.curr_level = 0;
    this.prev_level = 0;
    this.init_timer = 0;
    this.rendered_2 = false;
    this.rendered_1 = false;
    this.rendered_3 = false;

    var _col;
    var _row;
    var _map;
    this.getMap = function() {
        return _map;
    };

    var _indexOfRow;
    var _indexOfCol;

    this.getObstacleMap = function() {

        var originalMap = ObstacleMap[_type];
        var localMap = [];
        for (var i=0; i<originalMap.length; i++) {
            var newRow = [];
            for (var j=0; j<originalMap[0].length; j++) {
                newRow.push(originalMap[i][j]);
            }
            localMap.push(newRow);
        }

        for (var oneTypeOfNPC in _NPCs) {
            for (var i= 0; i < _NPCs[oneTypeOfNPC].length; i++) {
                var oneNPC =  _NPCs[oneTypeOfNPC][i];
                localMap[oneNPC.getPosition().y][oneNPC.getPosition().x] = 1;
            }
        }
        return localMap;
    };

    this.getGridSize = function() {
        return {
            col : _col,
            row : _row
        };
    };

    this.getIndexOfGrid = function() {
        return {
            rowIndex : _indexOfRow,
            colIndex : _indexOfCol
        };
    };

    this.addNPC = function(obj) {
        if (obj.getType() === "Player") {
            var a;
        }
        if (!_NPCs[obj.getType()]) {
            _NPCs[obj.getType()] = [];
        }
        obj.setId( _NPCs[obj.getType()].length);
        _NPCs[obj.getType()].push(obj);
    };
    this.removeNPC = function(obj) {
        var NPCs;
        if (!obj.insideBuilding()) {
            NPCs = obj.getGrid().getNPCs()[obj.getType()];
        } else {
            NPCs = obj.getBuilding().getNPCs()[obj.getType()]
        }

        var id = NPCs.indexOf(obj);
        _NPCs[obj.getType()].splice(id, 1);
    };
    this.removeAllNPCs = function() {
        for (var type in _NPCs) {
            delete _NPCs[type];
            _NPCs[type] = [];
        }
        for (var i=0; i<_buildingList.length; i++) {
            _buildingList[i].obj.removeAllNPCs();
        }
    };

    this.drawBackground = function(canvas, sx, sy, w, h) {
        var img = document.getElementById(_type);
        var context = canvas.getContext("2d");
        context.drawImage(img, 0, 0, img.width, img.height, sx, sy, w, h);
    };

    this.drawDebugBackground = function(canvas, sx, sy, w, h) {
        var gridWidth = w / _col;
        var gridHeight = h / _row;
        var context = canvas.getContext("2d");
        var obstacleMap = this.getObstacleMap();

        context.save();
        context.translate(sx, sy);
        var x, y;
        for (var i=0; i<_row; i++) {
            for (var j=0; j<_col; j++) {
                x = gridWidth * j;
                y = gridHeight * i;
                context.save();
                context.translate(x, y);
                if (obstacleMap[i][j] === 2) {
                    context.strokeStyle = "red";
                } else if (obstacleMap[i][j] === 1){
                    context.strokeStyle = "blue";
                } else {
                    context.strokeStyle = "black";
                }

                context.lineWidth = 1;
                context.strokeRect(0, 0, gridWidth, gridHeight);
                //context.fillText((i*mapSize.col+j).toString(), 0, DEBUG_GRID_SIZE);
                context.restore();
            }
        }
        context.restore();
    };

    this.drawDebugNPCs = function(canvas, sx, sy, w, h) {
        var gridWidth = w / _col;
        var gridHeight = h / _row;
        var context = canvas.getContext("2d");

        context.save();
        context.translate(sx, sy);
        var x, y;
        for (var type in _NPCs) {
            for (var i=0; i<_NPCs[type].length; i++) {
                var NPC = _NPCs[type][i];
                var position = NPC.getPosition();
                x = position.x * gridWidth;
                y = position.y * gridHeight;
                context.save();
                context.translate(x, y);
                NPC.drawDebug(context, 0, 0, gridWidth, gridHeight);
                context.restore();
            }
        }

        context.restore();
    };

    this.drawNPCs = function(canvas, sx, sy, w, h) {
        var gridWidth = w / _col;
        var gridHeight = h / _row;
        var context = canvas.getContext("2d");

        context.save();
        context.translate(sx, sy);
        var x, y;
        for (var type in _NPCs) {
            for (var i=0; i<_NPCs[type].length; i++) {
                var NPC = _NPCs[type][i];
                var position = NPC.getPosition();
                x = position.x * gridWidth;
                y = position.y * gridHeight;
                context.save();
                context.translate(x, y);
                NPC.draw(context, 0, 0, gridWidth, gridHeight);
                context.restore();
            }
        }

        context.restore();
    };

    this.init = function(args) {
        _col = args.col;
        _row = args.row;
        _map = args.map;

        _indexOfRow = args.indexOfRow;
        _indexOfCol = args.indexOfCol;

        _type = args.type;

        for (var type in args.NPCs) {
            _NPCs[type] = [];
            for (var j=0; j<args.NPCs[type].length; j++) {
                var NPC_arg = args.NPCs[type][j];
                NPC_arg.grid = this;
                NPC_arg.id = j;
                NPC_arg.type = type;
                switch(type) {
                    case "Army" :
                        var newArmy = new Army();
                        newArmy.init(NPC_arg);
                        newArmy.setState(
                            {
                                facing : "Down",
                                action : "Walk",
                                length : 2
                            }
                        );
                        _NPCs[type].push(newArmy);
                        break;
                    case "Player" :
                        player = new Player();
                        player.init(NPC_arg);
                        _NPCs[type].push(player);
                        break;
                    default :
                        break;
                }
            }
        }

    }
};
